package service

import (
	"sync"
	"time"

	"github.com/pkg/errors"

	"ldaccount/internal/conf"
	"ldaccount/pkg/log"
	"ldaccount/pkg/lueerror"
)

type Service struct {
	logger log.Factory
	cfg    *conf.Config
}

var service *Service

func InitService(logger log.Factory, cfg *conf.Config) {
	service = &Service{
		logger: logger,
		cfg:    cfg,
	}
}

func GetService() *Service {
	return service
}

var pubOnce, privOnce sync.Once

func parseLueerror(err error) lueerror.LueError {
	if err != nil {
		lueErr, ok := err.(lueerror.LueError)
		if ok {
			return lueErr
		} else {
			return lueerror.PgErr(err)
		}
	}
	return nil
}

// GenJwtToken 生成登陆token
func (srv *Service) GenJwtToken(GID, mobile, email, userName string) (string, lueerror.LueError) {
	privOnce.Do(LoadPrivKey(srv.cfg.Keys.PrivKey))
	now := time.Now()
	issuedAt := now.Unix()
	expiredAt := now.Add(srv.cfg.Keys.TokenDuration).Unix()

	payload := &JwtPayload{
		Mobile:   mobile,
		Email:    email,
		GID:      GID,
		UserName: userName,
	}

	token, err := GenJwtToken(payload, issuedAt, expiredAt)
	if err != nil {
		return "", lueerror.AuthGrantErr(err)
	}
	return token, nil
}

// VerifyToken token 校验
func (srv *Service) VerifyToken(token string) (*JwtPayload, lueerror.LueError) {
	if token == "" {
		return nil, lueerror.AuthGrantErr(errors.New("无效的token"))
	}
	token = ExtractToken(token)
	pubOnce.Do(LoadPubKey(srv.cfg.Keys.PubKey))

	payload, err := VerifyJwtToken(token)
	if err != nil {
		return nil, lueerror.AuthGrantErr(err)
	}
	if payload == nil {
		return nil, lueerror.AuthGrantErr(errors.New("jwt payload 为空"))
	}
	return payload, nil
}
